﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace GN.Pay.GatewayWeb.JumpNotify
{
    /// <summary>
    /// Hub会话管理
    /// </summary>
    public static class HubSessionManager
    {
        private static object sessionLock = new object();

        /// <summary>
        /// 会话集合
        /// </summary>
        private static Dictionary<string, HubApplySession> apply_Sessions =
             new Dictionary<string, HubApplySession>();

        /// <summary>
        /// 会话集合
        /// </summary>
        private static Dictionary<string, HubSession> connection_Sessions =
             new Dictionary<string, HubSession>();

        /// <summary>
        /// 注册会话
        /// </summary>
        /// <param name="HubSession">会话</param>
        /// <returns></returns>
        public static HubApplySession RegisterSession(HubSession session)
        {
            if (session == null)
            {
                throw new ArgumentNullException(nameof(session));
            }
            lock (sessionLock)
            {
                HubApplySession applySession;
                if (!apply_Sessions.TryGetValue(session.ApplyId, out applySession))
                {
                    applySession = new HubApplySession(session.ApplyId);
                    apply_Sessions[session.ApplyId] = applySession;
                }
                applySession.RegisterClient(session);
                connection_Sessions[session.ConnectionId] = session;
                return applySession;
            }
        }

        /// <summary>
        /// 移除会话
        /// </summary>
        /// <param name="applyId">申请Id</param>
        public static bool RemoveSessionForApply(string applyId)
        {
            if (applyId == null)
            {
                throw new ArgumentNullException(nameof(applyId));
            }
            lock (sessionLock)
            {
                HubApplySession applySession;
                if (apply_Sessions.TryGetValue(applyId, out applySession))
                {
                    apply_Sessions.Remove(applyId);
                    var sessions = applySession.Clients.ToArray();
                    foreach (var session in sessions)
                    {
                        connection_Sessions.Remove(session.ConnectionId);
                    }
                    applySession.Clear();
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }

        /// <summary>
        /// 移除会话
        /// </summary>
        /// <param name="connectionId">连接</param>
        public static bool RemoveSessionForConnect(string connectionId)
        {
            if (connectionId == null)
            {
                throw new ArgumentNullException(nameof(connectionId));
            }
            lock (sessionLock)
            {
                HubSession session;
                if (connection_Sessions.TryGetValue(connectionId, out session))
                {
                    HubApplySession applySession;
                    if (apply_Sessions.TryGetValue(session.ApplyId, out applySession))
                    {
                        applySession.RemoveClient(connectionId);
                        if (applySession.Count == 0)
                        {
                            apply_Sessions.Remove(session.ApplyId);
                        }  
                    }
                    connection_Sessions.Remove(connectionId);
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }

        /// <summary>
        /// 获取申请会话
        /// </summary>
        /// <param name="applyId">申请Id</param>
        /// <returns></returns>
        public static HubApplySession GetApplySession(string applyId)
        {
            if (applyId == null)
            {
                throw new ArgumentNullException(nameof(applyId));
            }
            lock (sessionLock)
            {
                HubApplySession applySession;
                if (apply_Sessions.TryGetValue(applyId, out applySession))
                {
                    return applySession;
                }
                return null;
            }
        }
    }
}